using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Xml;
using AmdInterface.HttpCom;
using BaseAmd.Mmt;
using Catastrophe.Common;

namespace SiemensAmd.Mmt
{
	public class MmtHttpPost : IToolsHanding, ISieToolsHanding
	{
		private DataTable _dbToolCusAb = new DataTable();

		private readonly List<string> _getRequistState = new List<string>
		{
			"HS_INIT", "HS_SOURCE_ALLOCATION", "HS_TARGET_ALLOCATION", "HS_ALLOCATED", "HS_TARGET_SEARCH", "HS_UNLOAD_PREPARING", "HS_LOAD_PREPARING", "HS_UNLOAD_START", "HS_LOAD_START", "HS_UNLOAD_COMMITING",
			"HS_SETTING_SOURCE_OPTIONS", "HS_SETTING_TARGET_OPTIONS", "HS_DEALOCATION", "HS_SOURCE_DEALOCATED", "HS_TARGET_DEALOCATED", "HS_UNLOAD_WAITING", "HS_LOAD_WAITING", "HS_LOAD_STARTED", "HS_UNLOAD_STARTED", "HS_HANDLING_READY",
			"HS_ABORTED", "Error"
		};

		public string HostIp { get; set; }

		public string ServerUrl { get; set; }

		public string SvcUrl { get; set; } = "/Actions";


		public string ContentType { get; set; } = "application/xml";


		public string CertificateName { get; set; } = "";


		public Tuple<HttpStatusCode?, XmlDocument> MmtPost(string body)
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.LoadXml(body);
			XmlDocument XMLResponse = null;
			HttpStatusCode? item = PlmHttpUtil.UploadXMLTransaction(this.ServerUrl + this.SvcUrl, xmlDocument, "POST", ref XMLResponse, this.CertificateName);
			return new Tuple<HttpStatusCode?, XmlDocument>(item, XMLResponse);
		}

		public Tuple<bool, string> GetMmtConfig()
		{
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.GetMmtConfig());
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				return new Tuple<bool, string>(item1: true, PlmHttpUtil.FormatXML(tuple.Item2.InnerXml));
			}
			return new Tuple<bool, string>(item1: false, tuple.Item1.ToString() + tuple.Item2.InnerText);
		}

		public Tuple<bool, string> CreateMasterData(string toolIdentify, int duploNo, int toolType, UserDataEntity entity = null)
		{
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.CreateMasterData(toolIdentify, toolType, entity));
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				return new Tuple<bool, string>(item1: true, PlmHttpUtil.FormatXML(tuple.Item2.InnerXml));
			}
			return new Tuple<bool, string>(item1: false, tuple.Item1.ToString() + tuple.Item2.InnerText);
		}

		public Tuple<bool, string, List<string>> QueryMasterData()
		{
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.QueryMasterData());
			List<string> list = new List<string>();
			if (tuple.Item2.DocumentElement != null)
			{
				foreach (XmlElement item in tuple.Item2.DocumentElement!)
				{
					string text = item.SelectSingleNode("TC_TP")?.SelectSingleNode("TC_TP2")?.InnerText;
					if (text != null && !list.Contains(text))
					{
						list.Add(text);
					}
				}
			}
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				return new Tuple<bool, string, List<string>>(item1: true, PlmHttpUtil.FormatXML(tuple.Item2.InnerXml), list);
			}
			return new Tuple<bool, string, List<string>>(item1: false, tuple.Item1.ToString() + tuple.Item2.InnerText, list);
		}

		public Tuple<bool, string> DeleteMasterData(string toolIdentify)
		{
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.DeleteMasterData(toolIdentify));
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				return new Tuple<bool, string>(item1: true, PlmHttpUtil.FormatXML(tuple.Item2.InnerXml));
			}
			return new Tuple<bool, string>(item1: false, tuple.Item1.ToString() + tuple.Item2.InnerText);
		}

		public Tuple<bool, string, MmtToolEntity> QueryByExternId(string nodeId, string externId)
		{
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.QueryByExternId(nodeId, externId));
			string item = PlmHttpUtil.FormatXML(tuple.Item2.InnerXml);
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				Tuple<List<MmtToolEntity>, List<string>> tuple2 = this.ResponseAnalyze(nodeId, "", tuple.Item2);
				return new Tuple<bool, string, MmtToolEntity>(item1: true, item, tuple2.Item1.FirstOrDefault());
			}
			return new Tuple<bool, string, MmtToolEntity>(item1: true, "", null);
		}

		public Tuple<bool, string, string, string> LoadUnloadCmd(string body)
		{
			string item = "";
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.LoadXml(body);
			xmlDocument.SelectSingleNode("Action/*[1]")!.InnerText = "1";
			XmlDocument XMLResponse = null;
			HttpStatusCode? httpStatusCode = PlmHttpUtil.UploadXMLTransaction(this.ServerUrl + this.SvcUrl, xmlDocument, "POST", ref XMLResponse, this.CertificateName);
			XmlNode xmlNode = XMLResponse?.DocumentElement;
			if (xmlNode != null && (xmlNode.InnerText == "Successful" || xmlNode.InnerText == "Started") && xmlNode.Attributes != null)
			{
				item = xmlNode.Attributes!["guid"]!.Value;
			}
			if (httpStatusCode == HttpStatusCode.OK)
			{
				return new Tuple<bool, string, string, string>(item1: true, PlmHttpUtil.FormatXML(XMLResponse.InnerXml), body, item);
			}
			return new Tuple<bool, string, string, string>(item1: false, XMLResponse.InnerText, body, item);
		}

		public Tuple<string, string> SendGetRequests(string guid = "", string actionId = "162")
		{
			try
			{
				string targetUrl = this.ServerUrl + this.SvcUrl + "?actionId=" + 162 + "&guid=" + guid;
				XmlDocument xmlResponse = null;
				HttpStatusCode? transaction = PlmHttpUtil.GetTransaction(targetUrl, ref xmlResponse, this.CertificateName);
				if (xmlResponse != null)
				{
					string item = xmlResponse.SelectSingleNode("Action")?.InnerText;
					return new Tuple<string, string>(item, xmlResponse.InnerXml);
				}
				return new Tuple<string, string>("No GET response received", "");
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		public DataTable GetImportToolsInfo()
		{
			return DataConverter.ConvertCusAbToDb<MmtToolEntity, MmtDataElemAttribute>();
		}

		public List<MmtToolEntity> ResponseAnalyzeAll(string nodeId, string magazine, XmlDocument doc)
		{
			XmlNode xmlNode = doc.SelectNodes("Action/MagList")?.Item(0);
			List<MmtToolEntity> list = new List<MmtToolEntity>();
			string magazine2 = "";
			string containerStateStr = "";
			if (xmlNode != null)
			{
				foreach (XmlNode item in xmlNode)
				{
					MmtToolEntity mmtToolEntity = new MmtToolEntity();
					if (item.Name == "Mag")
					{
						magazine2 = item.Attributes?["Name"]?.Value;
						containerStateStr = item.Attributes?["ContainerState"]?.Value;
						continue;
					}
					if (item.Name == "EmptyPlace")
					{
						string s = item.Attributes?["PlaceNo"]?.Value;
						if (int.TryParse(s, out var result))
						{
							mmtToolEntity.NodeId = nodeId;
							mmtToolEntity.MagPlace = result;
							mmtToolEntity.Magazine = magazine2;
							mmtToolEntity.ContainerStateStr = containerStateStr;
							mmtToolEntity.IsEmptyPlace = true;
							list.Add(mmtToolEntity);
							continue;
						}
					}
					if (item.Name == "ToolData")
					{
						XmlNode xmlNode3 = item.SelectSingleNode("DataElem");
						if (xmlNode3 != null)
						{
							foreach (XmlNode childNode in xmlNode3.ChildNodes)
							{
								switch (childNode.Name)
								{
								case "TC_TP":
								case "TDI":
									foreach (XmlNode childNode2 in childNode.ChildNodes)
									{
										this.GetXmlNodeValue(childNode2.Name, mmtToolEntity, childNode2.InnerXml);
									}
									break;
								case "DataElem":
									foreach (XmlNode childNode3 in childNode.ChildNodes)
									{
										string name = childNode3.Name;
										string text = name;
										if (!(text == "TC_DP") && !(text == "TC_MOP"))
										{
											continue;
										}
										foreach (XmlNode childNode4 in childNode3.ChildNodes)
										{
											this.GetXmlNodeValue(childNode4.Name, mmtToolEntity, childNode4.InnerXml);
										}
									}
									break;
								}
							}
						}
					}
					mmtToolEntity.NodeId = nodeId;
					mmtToolEntity.Magazine = magazine2;
					mmtToolEntity.ContainerStateStr = containerStateStr;
					mmtToolEntity.IsEmptyPlace = false;
					list.Add(mmtToolEntity);
				}
				return list;
			}
			return new List<MmtToolEntity>();
		}

		public Tuple<List<MmtToolEntity>, List<string>> ResponseAnalyze(string nodeId, string magazine, XmlDocument doc)
		{
			XmlNodeList elementsByTagName = doc.GetElementsByTagName("EmptyPlace");
			List<string> list = new List<string>();
			List<MmtToolEntity> item = this.ResponseAnalyzeAll(nodeId, magazine, doc);
			foreach (XmlNode item2 in elementsByTagName)
			{
				if (item2.Attributes != null)
				{
					list.Add(item2.Attributes!["PlaceNo"]?.Value);
				}
			}
			return new Tuple<List<MmtToolEntity>, List<string>>(item, list);
		}

		public void Initialize()
		{
			this.ServerUrl = "https://" + this.HostIp + "/amd/tools/v1";
			this.CertificateName = "CN=" + this.CertificateName;
			this._dbToolCusAb = DataConverter.ConvertCusAbToDb<MmtToolEntity, MmtDataElemAttribute>();
			PlmHttpUtil.AceptCertificate();
		}

		public Tuple<bool, string> ImportTool(string nodeId, string containerId, BaseMmtToolEntity baseEntity)
		{
			MmtToolEntity mmtToolEntity = (MmtToolEntity)baseEntity;
			Tuple<bool, string> tuple = this.CreateMasterData(mmtToolEntity.ToolIdentify, mmtToolEntity.DuploNo, mmtToolEntity.ToolType, mmtToolEntity.UserDataEntity);
			if (!tuple.Item1)
			{
				return new Tuple<bool, string>(item1: false, tuple.Item2);
			}
			string body = BodyBuild.ImportTools(nodeId, containerId, mmtToolEntity);
			Tuple<HttpStatusCode?, XmlDocument> tuple2 = this.MmtPost(body);
			string text = PlmHttpUtil.FormatXML(tuple2.Item2.InnerXml);
			return new Tuple<bool, string>(tuple2.Item1 == HttpStatusCode.OK, tuple2.Item1.ToString() + text);
		}

		public Tuple<bool, List<string>> QueryEmptyPlaces(string nodeId, string containerId)
		{
			List<string> list = new List<string>();
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.GetEmptyPlaces(nodeId, containerId));
			if (tuple.Item1 != HttpStatusCode.OK)
			{
				return new Tuple<bool, List<string>>(item1: false, new List<string>());
			}
			XmlNodeList elementsByTagName = tuple.Item2.GetElementsByTagName("EmptyPlace");
			foreach (XmlNode item in elementsByTagName)
			{
				if (item.Attributes != null)
				{
					list.Add(item.Attributes!["PlaceNo"]?.Value);
				}
			}
			return new Tuple<bool, List<string>>(item1: true, list);
		}

		public Tuple<bool, string> QueryToolsOnly(string nodeId, string containerId)
		{
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.GetToolsPlaces(nodeId, containerId));
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				return new Tuple<bool, string>(item1: true, PlmHttpUtil.FormatXML(tuple.Item2.InnerXml));
			}
			return new Tuple<bool, string>(item1: false, tuple.Item1.ToString() + tuple.Item2.InnerText);
		}

		public Tuple<bool, string> QueryMagAll(string nodeId, string containerId)
		{
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.GetAllPlaces(nodeId, containerId));
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				return new Tuple<bool, string>(item1: true, PlmHttpUtil.FormatXML(tuple.Item2.InnerXml));
			}
			return new Tuple<bool, string>(item1: false, tuple.Item1.ToString() + tuple.Item2.InnerText);
		}

		public Tuple<bool, string, List<BaseMmtToolEntity>, string> QueryToolEntitesAll(string nodeId, string containerId)
		{
			string allPlaces = BodyBuild.GetAllPlaces(nodeId, containerId);
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(allPlaces);
			string text = PlmHttpUtil.FormatXML(tuple.Item2.InnerXml);
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.LoadXml(text);
			string item = xmlDocument.SelectSingleNode("Action/MagList/Mag")?.Attributes?["ContainerState"]?.Value;
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				List<MmtToolEntity> source = this.ResponseAnalyzeAll(nodeId, containerId, tuple.Item2);
				List<BaseMmtToolEntity> item2 = ((IEnumerable<MmtToolEntity>)source).Select((Func<MmtToolEntity, BaseMmtToolEntity>)((MmtToolEntity x) => x)).ToList();
				return new Tuple<bool, string, List<BaseMmtToolEntity>, string>(item1: true, text, item2, item);
			}
			return new Tuple<bool, string, List<BaseMmtToolEntity>, string>(item1: false, tuple.Item1.ToString() + text, new List<BaseMmtToolEntity>(), "OFFLINE");
		}

		public Tuple<bool, string, BaseMmtToolEntity, string> QueryMasterAxisTool(string nodeId, string containerId)
		{
			Tuple<bool, string, List<BaseMmtToolEntity>, string> tuple = this.QueryToolEntitesAll(nodeId, containerId);
			List<MmtToolEntity> source = tuple.Item3.Select((BaseMmtToolEntity x) => x as MmtToolEntity).ToList();
			MmtToolEntity item = source.FirstOrDefault((MmtToolEntity x) => x.AToolmn == 9998);
			return new Tuple<bool, string, BaseMmtToolEntity, string>(tuple.Item1, tuple.Item2, item, tuple.Item4);
		}

		[Obsolete]
		public Tuple<bool, string, List<BaseMmtToolEntity>, List<string>, string> QueryToolEntites(string nodeId, string containerId)
		{
			string allPlaces = BodyBuild.GetAllPlaces(nodeId, containerId);
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(allPlaces);
			string text = PlmHttpUtil.FormatXML(tuple.Item2.InnerXml);
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.LoadXml(text);
			XmlNode xmlNode = xmlDocument.SelectSingleNode("Action/MagList/Mag");
			string item = "";
			if (xmlNode != null)
			{
				if (xmlNode.Attributes != null)
				{
					string value = xmlNode.Attributes!["Name"]!.Value;
				}
				if (xmlNode.Attributes != null)
				{
					item = xmlNode.Attributes!["ContainerState"]!.Value;
				}
			}
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				Tuple<List<MmtToolEntity>, List<string>> tuple2 = this.ResponseAnalyze(nodeId, containerId, tuple.Item2);
				List<BaseMmtToolEntity> item2 = ((IEnumerable<MmtToolEntity>)tuple2.Item1).Select((Func<MmtToolEntity, BaseMmtToolEntity>)((MmtToolEntity x) => x)).ToList();
				return new Tuple<bool, string, List<BaseMmtToolEntity>, List<string>, string>(item1: true, text, item2, tuple2.Item2, item);
			}
			return new Tuple<bool, string, List<BaseMmtToolEntity>, List<string>, string>(item1: false, tuple.Item1.ToString() + text, new List<BaseMmtToolEntity>(), new List<string>(), item);
		}

		public Tuple<bool, string> CheckMagState(List<MagListEntity> list)
		{
			string allPlacesMuti = BodyBuild.GetAllPlacesMuti(list);
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(allPlacesMuti);
			list.Clear();
			string text = PlmHttpUtil.FormatXML(tuple.Item2.InnerXml);
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.LoadXml(text);
			XmlNodeList xmlNodeList = xmlDocument.SelectNodes("Action/MagList");
			if (xmlNodeList != null)
			{
				foreach (XmlNode item in xmlNodeList)
				{
					string nodeId = item.Attributes?["NodeId"]?.Value;
					foreach (XmlNode item2 in item)
					{
						if (item2.Name.Equals("Mag"))
						{
							string magListState = "OFFLINE";
							string containerId = "";
							if (item2.Attributes != null)
							{
								containerId = item2.Attributes!["Name"]!.Value;
							}
							if (item2.Attributes?["ContainerState"] != null)
							{
								magListState = item2.Attributes!["ContainerState"]!.Value;
							}
							list.Add(new MagListEntity
							{
								NodeId = nodeId,
								ContainerId = containerId,
								MagListState = magListState
							});
						}
					}
				}
			}
			return new Tuple<bool, string>(tuple.Item1 == HttpStatusCode.OK, text);
		}

		public Tuple<bool, string, List<BaseMmtToolEntity>, List<string>> QueryToolEntites(List<MagListEntity> list)
		{
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.GetAllPlacesMuti(list));
			string xml = PlmHttpUtil.FormatXML(tuple.Item2.InnerXml);
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.LoadXml(xml);
			XmlNodeList xmlNodeList = xmlDocument.SelectNodes("Action/MagList/Mag");
			foreach (XmlNode item in xmlNodeList)
			{
				string text = "";
				if (item != null)
				{
					if (item.Attributes != null)
					{
						string value = item.Attributes!["Name"]!.Value;
					}
					if (item.Attributes != null)
					{
						text = item.Attributes!["ContainerState"]!.Value;
					}
				}
			}
			return null;
		}

		public Tuple<bool, string, BaseMmtToolEntity> QueryToolSingle(string nodeId, string duploNo, string toolIdentify)
		{
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.QueryByIdentify(nodeId, duploNo, toolIdentify));
			string item = PlmHttpUtil.FormatXML(tuple.Item2.InnerXml);
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				Tuple<List<MmtToolEntity>, List<string>> tuple2 = this.ResponseAnalyze(nodeId, "", tuple.Item2);
				return new Tuple<bool, string, BaseMmtToolEntity>(item1: true, item, tuple2.Item1.FirstOrDefault());
			}
			return new Tuple<bool, string, BaseMmtToolEntity>(item1: true, "", null);
		}

		public Tuple<bool, string> DeleteTools(string nodeId, string containerId, List<int> locBuffer)
		{
			Tuple<HttpStatusCode?, XmlDocument> tuple = this.MmtPost(BodyBuild.DeleteTrashTools(nodeId, containerId, locBuffer));
			if (tuple.Item1 == HttpStatusCode.OK)
			{
				string xml = PlmHttpUtil.FormatXML(tuple.Item2.InnerXml);
				XmlDocument xmlDocument = new XmlDocument();
				xmlDocument.LoadXml(xml);
				XmlNodeList xmlNodeList = xmlDocument.SelectNodes("Action/ActionDeleteTool");
				bool item = xmlNodeList != null;
				if (xmlNodeList != null)
				{
					foreach (XmlNode item2 in xmlNodeList)
					{
						string text = item2?.InnerText;
						if (text != "Deleted")
						{
							item = false;
						}
					}
				}
				return new Tuple<bool, string>(item, PlmHttpUtil.FormatXML(tuple.Item2.InnerXml));
			}
			return new Tuple<bool, string>(item1: false, tuple.Item1.ToString() + tuple.Item2.InnerText);
		}

		public Tuple<bool, string, string, string> LoadUnload(string srcDeviceId, string srcMag, int srcLoc, string dstDeviceId, string dstMag, string toolIdentify, int dstLoc, int duploNo = 1)
		{
			string body = BodyBuild.MoveTools(srcDeviceId, srcMag, srcLoc, dstDeviceId, dstMag, toolIdentify, dstLoc, duploNo);
			return this.LoadUnloadCmd(body);
		}

		public bool AbortTd(string state)
		{
			return this._getRequistState.IndexOf(state) >= 17;
		}

		private void GetXmlNodeValue(string name, MmtToolEntity entity, string value)
		{
			try
			{
				DataRow row = this._dbToolCusAb.Select("Adr='" + name + "'").FirstOrDefault();
				PropertyInfo[] properties = typeof(MmtToolEntity).GetProperties();
				if (row != null)
				{
					PropertyInfo propertyInfo = properties.FirstOrDefault((PropertyInfo x) => x.Name == row["Name"].ToString());
					if (propertyInfo != null)
					{
						DataConverter.PropertySetValue(entity, propertyInfo, value);
					}
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}
	}
}
